package com.blue.common.aop;

import com.blue.common.annotation.ReplaceParam;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author nanjie.chen
 * Created on 2024/4/28
 * 请求参数添加替换符
 */
@Component
@Aspect
public class ReplaceParamAop {
    @Pointcut("@annotation(com.blue.common.annotation.ReplaceParam)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object replaceParam(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof ReplaceParam fuzzy) {
                editParam(proceedingJoinPoint, fuzzy);
            }
        }
        return proceedingJoinPoint.proceed();
    }

    private void editParam(ProceedingJoinPoint proceedingJoinPoint, ReplaceParam fuzzy) throws IllegalAccessException {
        String value = fuzzy.value();
        value = value.replaceAll("\\s+", "");
        String[] fields = value.split(",");
        if (fields.length == 0) {
            return;
        }
        Object[] args = proceedingJoinPoint.getArgs();
        for (Object arg : args) {
            Class<?> aClass = arg.getClass();
            for (String field : fields) {
                Field declaredField;
                try {
                    declaredField = aClass.getDeclaredField(field);
                } catch (NoSuchFieldException ignored) {
                    continue;
                }
                declaredField.setAccessible(true);
                Object obj = declaredField.get(arg);
                if (obj instanceof String && StringUtils.isNotBlank((String) obj)) {
                    String symbol = fuzzy.symbol();
                    String position = fuzzy.position();
                    switch (position) {
                        case "both":
                            declaredField.set(arg, symbol + (String) obj + symbol);
                            break;
                        case "left":
                            declaredField.set(arg, symbol + (String) obj);
                            break;
                        case "right":
                            declaredField.set(arg, (String) obj + symbol);
                            break;
                    }
                }
            }
        }
    }
}
